package com.xifly.jwt.util;

import com.xifly.jwt.repository.UserRepository;
import io.jsonwebtoken.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Component
public class JwtUtil {

    private static UserRepository userRepository;

    @Autowired
    private JwtUtil(UserRepository userRepository){
        JwtUtil.userRepository = userRepository;
    }

    public static final long EXPIRATION_TIME = 3600_000_000L;
    static final String SECRET = "ThisIsASecret";
    static final String TOKEN_PREFIX = "Bearer";
    static final String HEADER_STRING = "Authorization";

    public static String generateToken(String username,Date generateTime){
        HashMap<String, Object> map = new HashMap<>();

        map.put("username", username);
        map.put("generateTime",generateTime);
        String jwt = Jwts.builder()
                .setClaims(map)
                .setExpiration(new Date(generateTime.getTime() + EXPIRATION_TIME))
                .signWith(SignatureAlgorithm.HS256,SECRET)
                .compact();
        return jwt;
    }

    public static Map<String,Object> validateToken(String token){
        Map<String,Object> resp = new HashMap<String,Object>();
        if (token != null){
            try {
                Map<String,Object> body = Jwts.parser()
                        .setSigningKey(SECRET)
                        .parseClaimsJws(token.replace(TOKEN_PREFIX,""))
                        .getBody();
                String username = (String) (body.get("username"));
                Date generateTime = new Date((Long)body.get("generateTime"));


                if (username == null || username.isEmpty()){
                    resp.put("ERR_MSG",Constants.ERR_MSG_USERNAME_EMPTY);
                    return resp;
                }

                if(userRepository.findByUsername(username).getLastLoginTime().after(generateTime)){
                    resp.put("ERR_MSG",Constants.ERR_MSG_LOGIN_DOU);
                    return resp;
                }

                resp.put("username",username);
                resp.put("generateTime",generateTime);

                return resp;

            } catch (SignatureException | MalformedJwtException e){
                resp.put("ERR_MSG",Constants.ERR_MSG_TOKEN_ERR);
                return resp;
            } catch (ExpiredJwtException e){
                resp.put("ERR_MSG",Constants.ERR_MSG_TOKEN_EXP);
                return resp;
            }

        }
        else {
            resp.put("ERR_MSG",Constants.ERR_MSG_TOKEN_EMPTY);
            return resp;
        }
    }
}
